import {
	round
} from "./digit";

/**
 * @description 选择比赛的过关方式
 * @param {list} datas	数据
 * [{matchId:,matchNum:,matchNumStr:,selectType:{code:,name:,},selectItem:{n,x,v,pei,c},single:,}]
 */
export function footballPass(datas) {
	const passMap = {
		"1": {
			type: 1,
			name: '单关',
			x: false

		},
		"2": {
			type: 2,
			name: '2串1',
			x: false
		},
		"3": {
			type: 3,
			name: '3串1',
			x: false
		},
		"4": {
			type: 4,
			name: '4串1',
			x: false
		},
		"5": {
			type: 5,
			name: '5串1',
			x: false
		},
		"6": {
			type: 6,
			name: '6串1',
			x: false
		},
		"7": {
			type: 7,
			name: '7串1',
			x: false
		},
		"8": {
			type: 8,
			name: '8串1',
			x: false
		}
	};
	//如果只选择一场比赛，就判断是否单关
	//如果选择两场以上的比赛，那么就开始判断串串
	//如果有半全场，总进球，比分，那么最多只能是4串1，其他的，最多8串1
	//先分组，看有几场比赛
	const groupDatas = datas.reduce((map, item) => {
		const group = map.get(item.matchId) || []
		group.push(item)
		return map.set(item.matchId, group)
	}, new Map())

	//只有一场，我们就看看胜平负是不是单关，是就显示单关
	let n = groupDatas.size;

	//判断有几种类型（1都是单关、2都是其他、3都是胜平负、4混合）
	//[{matchId:,matchNum:,matchNumStr:,selectType:{code:,name:,},selectItem:{n,x,v,pei,c},single:,}]
	let isSingle = true;
	for (const m of datas) {
		if (!m.single) {
			isSingle = false;
			break;
		}
	}
	const typeGroupDatas = datas.reduce((map, item) => {
		const group = map.get(item.selectType.code) || []
		group.push(item)
		return map.set(item.selectType.code, group)
	}, new Map())
	const keys = Array.from(typeGroupDatas.keys());
	//spf、rspf、crs、ttg、bqc
	const isSpfExist = keys.includes("spf");
	const isRspfExist = keys.includes("rspf");
	const isCrsExist = keys.includes("crs");
	const isTtgExist = keys.includes("ttg");
	const isBqcExist = keys.includes("bqc");

	let codeType = 4; //默认是混合
	//全部是胜平负
	if ((isSpfExist || isRspfExist) && !isCrsExist && !isTtgExist && !isBqcExist) {
		codeType = 3; //都是胜平负
	}
	//全是半全场、比分、总进球
	if ((!isSpfExist && !isRspfExist) && (isCrsExist || isTtgExist || isBqcExist)) {
		codeType = 2;
	}
	let pass = [];
	//生成过关
	let pns = []
	if (isSingle) {
		//添加单关
		pns.push(1);
	}
	//添加串串
	let cn = n;
	if (n > 8 && codeType == 3) {
		cn = 8;
	}
	if (n > 4 && codeType == 2) {
		cn = 4;
	}
	if (n > 4 && codeType == 4) {
		cn = 4;
	}
	for (let i = 2; i < cn + 1; i++) {
		pns.push(i)
	}
	//找到串串
	for (const k of pns) {
		pass.push(passMap[k]);
	}
	//默认选择最后一个过关
	if (pass.length) {
		pass[pass.length - 1].x = true;
	}
	//构造返回数据
	const resData = {
		pass: pass, //符合的过关方式
		selectNum: groupDatas.size, //总选择的场次
		selectMatchs: groupDatas //根据场次分组好的选项
	}

	return resData;
}

/**
 * @description 计算足球竞猜的购买金额及预计奖金
 * @param {list} datas		数据
 * @param {number} pass		过关方式
 * @param {number} num		倍数
 */
export function getBonus(data, pass, num) {
	//选择的过关
	let selectps = pass.filter(x => x.x == true);
	//构造返回数据
	let rebonus = {
		min: 0,
		max: 0,
		num: 0,
		buyTotal:0
	}
	for (let p of selectps) {
		const bouns = colBonus(data, p.type, num);
		rebonus.min += bouns.min;
		rebonus.max += bouns.max;
		rebonus.num += bouns.num;
		rebonus.buyTotal += bouns.buyTotal;
	}

	return rebonus;
}
/**
 * 根据过关计算奖金
 * @param {list} datas		数据
 * @param {number} pass		过关方式 默认是单关
 * @param {number} num		倍数 默认1倍
 */
function colBonus(data, pass = 1, bei = 1) {
	//找出最小的赔率
	let min = 1000000;
	let max = 0;
	//有多少注
	let num = 0;
	switch (pass) {
		case 1: //单关
			for (let vs of data.values()) {
				for (let v of vs) {
					num += 1;
					const ps = v.selectItem.v;
					max += ps;
					if (ps < min) {
						min = ps;
					}
				}
			}
			break;
		default:
			//对比赛进行串串组合
			const combs = getCombinations(Array.from(data.keys()),pass);
			//进行串串奖金计算
			for(const com of combs){
				let arraysToCombine = [];
				for(let i = 0;i<pass;i++){
					arraysToCombine.push(data.get(com[i]).map(item => item.selectItem.v));
				}
				const fangans = cartesianProductOfArrays(arraysToCombine);
				//找出最大，最小奖金，
				for(const f of fangans){
					num += 1;
					// 求积
					const ps = f.reduce((acc, curr) => acc * curr, 1);
					max += ps;
					if (ps < min) {
						min = ps;
					}
				}
			}
			break;
	}
	min = round(min * bei * 2, 2);
	max = round(max * bei * 2, 2);


	return {
		min: min,
		max: max,
		num: num,
		buyTotal:num*2*bei
	}
}
/**
 * 排列组合
 * @param {Object} arr
 * @param {Object} size
 */
function getCombinations(arr, size) {
  const result = [];
  
  function combine(start, current) {
    if (current.length === size) {
      result.push([...current]);
      return;
    }
    
    for (let i = start; i < arr.length; i++) {
      current.push(arr[i]);
      combine(i + 1, current);
      current.pop();
    }
  }
  
  combine(0, []);
  return result;
}
/**
 * 多数组排列组合
 * @param {Object} arrays
 */
function cartesianProductOfArrays(arrays) {
  return arrays.reduce((a, b) => {
    return a.flatMap(x => b.map(y => [...x, y]));
  }, [[]]);
}